//
// Created by lz on 3/14/21.
//

#ifndef MUDUO_NET_TCPCLIENT_H_
#define MUDUO_NET_TCPCLIENT_H_

#include "base/Mutex.h"
#include "net/TcpConnection.h"


namespace lzweb
{
	namespace net
	{
		class Connector;
		using ConnectorPtr = std::shared_ptr<Connector>;

		class TcpClient: noncopyable
		{
		 public:
			// TcpClient(EventLoop* loop);
			// TcpClient(EventLoop* loop, const string& host, uint16_t port);
			TcpClient(EventLoop* loop,
				const InetAddress& serverAddr,
				const string& nameArg);

			~TcpClient();

			void connect();
			void disconnect();
			void stop();

			TcpConnectionPtr connection() const
			{
				MutexLockGuard lock(mutex_);
				return connection_;
			}

			EventLoop* getLoop() const { return loop_; }
			bool retry() const { return retry_; }
			void enableRetry() { retry_ = true; }
			const string& name() const
			{
				return name_;
			}

			/// set connection callback
			/// not thread safe
			void setConnectionCallback(ConnectionCallback cb)
			{ connectionCallback_ =  std::move(cb); }


			/// Set message callback.
			/// Not thread safe.
			void setMessageCallback(MessageCallback cb)
			{ messageCallback_ = std::move(cb); }

			/// Set write complete callback.
			/// Not thread safe.

			void setWriteCompleteCallback(WriteCompleteCallback cb)
			{ writeCompleteCallback_ = std::move(cb); }

		 private:

			// Not thread safe, but in loop
			void newConnection(int sockfd);
			// Not thread safe, but in loop
			void removeConnection(const TcpConnectionPtr& connection);

			EventLoop* loop_;
		 	ConnectorPtr connector_; // avoid revealing Connector  客户端的连接器
		 	const string name_;
		 	ConnectionCallback connectionCallback_;
		 	MessageCallback messageCallback_;
		 	WriteCompleteCallback writeCompleteCallback_;
			bool retry_;  //atomic
			bool connect_;  //atomic
			// always in loop thread
			int nextConnId_;
			mutable MutexLock mutex_;
			TcpConnectionPtr connection_ GUARDED_BY(mutex_);  //一个TcpClient代表一个客户端连接


		};

	} // namespace net
} // namespace lzweb

#endif //MUDUO_NET_TCPCLIENT_H_
